RDS for Oracle環境でData Pumpを利用する
西澤です。RDS for Oracle環境で、Data Pumpを試す機会があったので、まとめておきたいと思います。
Data Pumpとは?
Oracleのバックアップリストアツールと言えば、以前よりあるexp/impコマンドが有名ですが、10gより非推奨となっています。exp/impコマンドはクライアントツールだった為、サーバとクライアント間でのデータ転送が必要でしたが、Data Pumpはデータベースサーバ側で処理される為、性能が大きく改善されています。ただし、データベースサーバ側のディスクを利用する為、ディスク使用量には注意が必要です。
Oracle Data Pump は、Oracle のインストールから Amazon RDS DB インスタンスに大量のデータを移行する際に推奨される方法です。Oracle Data Pump は、次のようなさまざまなシナリオで使用できます。
- Oracle データベースを使用した Amazon EC2 インスタンスから Oracle DB インスタンスにデータをインポートする
- Oracle DB インスタンス上のデータベースから別の Oracle DB インスタンスにデータをインポートする
- VPC 内の Oracle DB インスタンス上のデータベースから別の Oracle DB インスタンスにデータをインポートする (VPC の有無は問わない)
- ローカルの Oracle データベースから Amazon RDS DB インスタンスにデータをインポートする
Amazon RDS での Oracle へのデータのインポート - Amazon Relational Database Service
Data Pumpを利用したバックアップ/リストアの概要
RDS for Oracle環境でもData Pumpを利用することができますが、データベースサーバの完全な管理者権限があるわけではありませんので、DBMS_DATAPUMP
やDBMS_FILE_TRANSFER
等のプロシージャを利用する必要があります。今回は、RDS for Oracle同士でData Pumpを利用できるかを検証しました。本来であれば、RDSスナップショット機能を利用したバックアップ/リストアが手順も簡易で利用しやすいのですが、より高速にバックアップ/リストアをすることができないか調査の為にお客様からのお問合わせに基づき検証を行いました。
- oracledb1にてDBMS_DATAPUMPを利用してデータをDATA_PUMP_DIRにダンプファイルを出力
- oracledb1からoracledb2に対してデータベースリンクを作成
- oracledb1のDATA_PUMP_DIRからoracledb2のDATA_PUMP_DIRにダンプファイルを転送
- oracledb2にてDBMS_DATAPUMPを利用してDATA_PUMP_DIRのダンプファイルからリストア
RDS for Oracle環境でData Pumpを試してみた
それでは、順番に進めてみます。今回は下記のバージョンで試してみました。
select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Release 11.2.0.4.0 - 64bit Production PL/SQL Release 11.2.0.4.0 - Production CORE 11.2.0.4.0 Production TNS for Linux: Version 11.2.0.4.0 - Production NLSRTL Version 11.2.0.4.0 - Production 5 rows selected
RDS環境ではDATA_PUMP_DIR
を変更することはできませんので、デフォルトのパスが利用されます。
SELECT directory_name, directory_path FROM dba_directories WHERE directory_name='DATA_PUMP_DIR'; DIRECTORY_NAME DIRECTORY_PATH ------------------------------ ---------------------- DATA_PUMP_DIR /rdsdbdata/datapump 1 rows selected
DBMS_DATAPUMPでエクスポート
書式に慣れるまでがちょっとわかりづらいですが、基本的には下記の通りに実行すればバックアップが取得可能です。ダンプファイルやログファイルを指定している"filename"とスキーマ名(下記例では"ADMIN"としています)だけ環境に合わせて修正してご利用ください。
DECLARE hdnl NUMBER; BEGIN hdnl := DBMS_DATAPUMP.open( operation => 'EXPORT', job_mode => 'SCHEMA', job_name=>null); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'tab1.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.add_file( handle => hdnl, filename => 'exp.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_EXPR','IN (''ADMIN'')'); DBMS_DATAPUMP.start_job(hdnl); END; / anonymous block completed
ちなみに、スキーマ全体ではなく、特定のテーブルのみを対象として、エクスポートをする場合は下記のような指定(下記は、TABLE_A,TABLE_B,TABLE_Cのみを対象とする例)が可能でした。また、"NOT IN"を利用することで特定のテーブルを除外することもできるようです。
DECLARE hdnl NUMBER; BEGIN hdnl := DBMS_DATAPUMP.open( operation => 'EXPORT', job_mode => 'SCHEMA', job_name=>null); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'expdb_tables.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.add_file( handle => hdnl, filename => 'expdb_tables.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.METADATA_FILTER( handle => hdnl, name => 'SCHEMA_EXPR', value => 'IN (SCHEMA_NAME)'); DBMS_DATAPUMP.METADATA_FILTER( handle => hdnl, name => 'NAME_EXPR', value => 'IN (TABLE_A,TABLE_B,TABLE_C)', object_path=>'TABLE'); DBMS_DATAPUMP.start_job(hdnl); END; /
DATA_PUMP_DIRの確認方法
ちなみに、作成されたログファイルもRDS内のディレクトリに作成される為、下記のように参照します。
# DATA_PUMP_DIR内のファイル一覧取得 SELECT * FROM TABLE(RDSADMIN.RDS_FILE_UTIL.LISTDIR('DATA_PUMP_DIR')) ORDER BY MTIME; FILENAME TYPE FILESIZE MTIME --------------------------------- ---------- ---------------------- --------------- tab1.dmp file 188772352 17-04-05 exp.log file 30581 17-04-05 datapump/ directory 4096 17-04-05 3 rows selected
# ログファイルの確認方法 SELECT TEXT FROM TABLE(RDSADMIN.RDS_FILE_UTIL.READ_TEXT_FILE('DATA_PUMP_DIR','exp.log')); TEXT ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- "ADMIN"."SYS_EXPORT_SCHEMA_01"を起動しています: BLOCKSメソッドを使用して見積り中です... オブジェクト型SCHEMA_EXPORT/TABLE/TABLE_DATAの処理中です BLOCKSメソッドを使用した見積り合計: 245.2 MB オブジェクト型SCHEMA_EXPORT/USERの処理中です オブジェクト型SCHEMA_EXPORT/SYSTEM_GRANTの処理中です オブジェクト型SCHEMA_EXPORT/ROLE_GRANTの処理中です オブジェクト型SCHEMA_EXPORT/DEFAULT_ROLEの処理中です オブジェクト型SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMAの処理中です オブジェクト型SCHEMA_EXPORT/SEQUENCE/SEQUENCEの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/TABLEの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/COMMENTの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/INDEXの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/FUNCTIONAL_INDEX/INDEXの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINTの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICSの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/FUNCTIONAL_INDEX/INDEX_STATISTICSの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINTの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/TRIGGERの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICSの処理中です . . "ADMIN"."TABLE1" 46.36 MB 6259行がエクスポートされました . . "ADMIN"."TABLE2" 46.50 MB 5463行がエクスポートされました . . "ADMIN"."TABLE3" 19.79 MB 8151行がエクスポートされました . . "ADMIN"."TABLE4" 0 KB 0行がエクスポートされました ::: マスター表"ADMIN"."SYS_EXPORT_SCHEMA_01"は正常にロード/アンロードされました ****************************************************************************** ADMIN.SYS_EXPORT_SCHEMA_01に設定されたダンプ・ファイルは次のとおりです: /rdsdbdata/datapump/tab1.dmp ジョブ"ADMIN"."SYS_EXPORT_SCHEMA_01"が水 4月 5 13:31:18 2017 elapsed 0 00:01:41で正常に完了しました 301 rows selected
データベースリンク作成
oracledb2側で事前に作成したユーザを利用してoracledb1からデータベースリンクを作成します。今回は管理者ユーザとして作成したadminをそのまま使ってしまいました。
create database link dst_rds connect to admin identified by UserPassword using '(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=oracledb2.xxxxxxxxxxxx.us-west-2.rds.amazonaws.com)(PORT=1521))(CONNECT_DATA=(SID=ORCL)))'; create database linkが正常に実行されました。
ダンプファイル転送
ダンプファイルは作成したデータベースリンクを介して、oracledb1からDBMS_FILE_TRANSFER
パッケージを利用して転送を行います。
BEGIN DBMS_FILE_TRANSFER.PUT_FILE( source_directory_object => 'DATA_PUMP_DIR', source_file_name => 'tab1.dmp', destination_directory_object => 'DATA_PUMP_DIR', destination_file_name => 'tab1_copied.dmp', destination_database => 'dst_rds' ); END; / anonymous block completed
しばらく待ってから、oracledb2側でダンプファイルがDATA_PUMP_DIR
に配置されたことを確認します。
SELECT * FROM TABLE(RDSADMIN.RDS_FILE_UTIL.LISTDIR('DATA_PUMP_DIR')) ORDER BY MTIME; FILENAME TYPE FILESIZE MTIME ---------------------------- ---------- ---------------------- ------------------------- datapump/ directory 4096 17-04-05 tab1_copied.dmp file 188772352 17-04-05 2 rows selected
DBMS_DATAPUMPでインポート
ここまで来ればもう操作はほとんど同じです。oracldb2側でDBMS_DATAPUMP
パッケージを利用してインポートを行います。
DECLARE hdnl NUMBER; BEGIN hdnl := DBMS_DATAPUMP.open( operation => 'IMPORT', job_mode => 'SCHEMA', job_name=>null); DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'tab1_copied.dmp', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_dump_file); DBMS_DATAPUMP.add_file( handle => hdnl, filename => 'imp.log', directory => 'DATA_PUMP_DIR', filetype => dbms_datapump.ku$_file_type_log_file); DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_EXPR','IN (''ADMIN'')'); DBMS_DATAPUMP.start_job(hdnl); END; / anonymous block completed
インポート結果を確認しておきましょう。
SELECT TEXT FROM TABLE(RDSADMIN.RDS_FILE_UTIL.READ_TEXT_FILE('DATA_PUMP_DIR','imp.log')); TEXT ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- マスター表"ADMIN"."SYS_IMPORT_SCHEMA_01"は正常にロード/アンロードされました "ADMIN"."SYS_IMPORT_SCHEMA_01"を起動しています: オブジェクト型SCHEMA_EXPORT/USERの処理中です ORA-31684: オブジェクト型USER:"ADMIN"はすでに存在します オブジェクト型SCHEMA_EXPORT/SYSTEM_GRANTの処理中です ORA-31685: 権限が不十分なため、オブジェクト型SYSTEM_GRANT:"ADMIN"が失敗しました。エラー文は次のとおりです: GRANT EXEMPT REDACTION POLICY TO "ADMIN" WITH ADMIN OPTION ORA-31685: 権限が不十分なため、オブジェクト型SYSTEM_GRANT:"ADMIN"が失敗しました。エラー文は次のとおりです: GRANT ALTER DATABASE LINK TO "ADMIN" WITH ADMIN OPTION ORA-31685: 権限が不十分なため、オブジェクト型SYSTEM_GRANT:"ADMIN"が失敗しました。エラー文は次のとおりです: GRANT ALTER PUBLIC DATABASE LINK TO "ADMIN" WITH ADMIN OPTION ORA-31685: 権限が不十分なため、オブジェクト型SYSTEM_GRANT:"ADMIN"が失敗しました。エラー文は次のとおりです: GRANT EXEMPT IDENTITY POLICY TO "ADMIN" WITH ADMIN OPTION ORA-31685: 権限が不十分なため、オブジェクト型SYSTEM_GRANT:"ADMIN"が失敗しました。エラー文は次のとおりです: GRANT EXEMPT ACCESS POLICY TO "ADMIN" WITH ADMIN OPTION オブジェクト型SCHEMA_EXPORT/ROLE_GRANTの処理中です ORA-31685: 権限が不十分なため、オブジェクト型ROLE_GRANT:"ADMIN"が失敗しました。エラー文は次のとおりです: GRANT "CONNECT" TO "ADMIN" WITH ADMIN OPTION ORA-31685: 権限が不十分なため、オブジェクト型ROLE_GRANT:"ADMIN"が失敗しました。エラー文は次のとおりです: GRANT "RESOURCE" TO "ADMIN" WITH ADMIN OPTION ORA-31685: 権限が不十分なため、オブジェクト型ROLE_GRANT:"ADMIN"が失敗しました。エラー文は次のとおりです: GRANT "AQ_USER_ROLE" TO "ADMIN" WITH ADMIN OPTION ORA-31685: 権限が不十分なため、オブジェクト型ROLE_GRANT:"ADMIN"が失敗しました。エラー文は次のとおりです: GRANT "RECOVERY_CATALOG_OWNER" TO "ADMIN" WITH ADMIN OPTION ORA-31685: 権限が不十分なため、オブジェクト型ROLE_GRANT:"ADMIN"が失敗しました。エラー文は次のとおりです: GRANT "CTXAPP" TO "ADMIN" WITH ADMIN OPTION オブジェクト型SCHEMA_EXPORT/DEFAULT_ROLEの処理中です オブジェクト型SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMAの処理中です オブジェクト型SCHEMA_EXPORT/SEQUENCE/SEQUENCEの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/TABLEの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/TABLE_DATAの処理中です . . "ADMIN"."TABLE1" 46.36 MB 6259行がインポートされました . . "ADMIN"."TABLE2" 46.50 MB 5463行がインポートされました . . "ADMIN"."TABLE3" 19.79 MB 8151行がインポートされました . . "ADMIN"."TABLE4" 0 KB 0行がインポートされました ::: オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/INDEXの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/FUNCTIONAL_INDEX/INDEXの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINTの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICSの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/FUNCTIONAL_INDEX/INDEX_STATISTICSの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINTの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/TRIGGERの処理中です オブジェクト型SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICSの処理中です ジョブ"ADMIN"."SYS_IMPORT_SCHEMA_01"が完了しましたが、11エラーが水 4月 5 14:44:06 2017 elapsed 0 00:01:10で発生しています 316 rows selected
システム系のテーブルは権限不足でエラーとなっていましたが、移行したかったテーブル情報は全て移行されていることを確認できました。
最初の注意に記載した通り、RDS側にファイルが生成されることになる為、ゴミ掃除も忘れずやっておきましょう。例えば、エクスポートログを削除する場合は下記のようになります。
EXEC UTL_FILE.FREMOVE('DATA_PUMP_DIR','exp.log'); anonymous block completed
まとめ
OracleのDBMS_DATAPUMPプロシージャを利用したエクスポート/インポートを試してみました。始めは少々とっつきにくい印象でしたが、データの受け渡し性能が高いことは間違いないので、やってみると非常に便利であることがわかりました。やっぱり手を動かすの大事ですね。
どこかの誰かのお役に立てば嬉しいです。